<?php

namespace App\Console\Scripts\Counter;

use App\Consts\GlobalConst;
use App\Consts\GlobalCounterConst;
use App\Consts\GlobalNoteConst;
use App\Models\Cache\CacheKey;
use App\Models\SysArticle;
use App\Models\SysNote;
use App\Models\User;
use Illuminate\Database\Query\Builder;

/**
 * 用户文章计数统计脚本
 * Class ArticleCounterCommand
 * @package App\Console\Scripts\Counter
 */
class UserArticleCounterCommand extends BaseCounterCommand
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'counter:user-article {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'counter for user article';

    /**
     * 用户文章公开笔记统计
     * @return int
     */
    public function notePublic()
    {
        return $this->_setNoteCount(GlobalNoteConst::IS_PUBLIC, GlobalCounterConst::COUNT_PUBLIC_NOTE);
    }

    /**
     * 用户文章私有笔记统计
     * @return int
     */
    public function noteSelf()
    {
       return $this->_setNoteCount(GlobalNoteConst::IS_NOT_PUBLIC, GlobalCounterConst::COUNT_SELF_NOTE);
    }

    /**
     * 用户文章笔记统计
     * @param $type
     * @param $key
     * @return int
     */
    private function _setNoteCount($type, $key)
    {
        $subMode = $this->_getSubModel();
        $finish = SysArticle::getSubModel(function (Builder $query) {
            $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
        }, ['id', 'article_id'])->count();
        // 每 100 单位合并处理一次
        $subMode->chunkById(100, function ($list) use ($finish, $type, $key) {
            foreach ($list as $item) {
                static $index = 1;
                $id = $item->user_id;
                $articleIdAry = SysArticle::getSubModel(function (Builder $query) use ($id) {
                    $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
                    $query->where('author_id', $id);
                }, ['id', 'article_id'])->pluck('article_id');
                foreach ($articleIdAry as $articleId) {
                    $total = SysNote::getSubModel(function (Builder $query) use ($articleId, $id, $type) {
                        $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
                        $query->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD);
                        $query->where('article_id', $articleId);
                        $query->where('user_id', $id);
                        $query->where('is_public', $type);
                    }, ['id'])->count();
                    // set cache
                    $cacheKey = $this->setHashCache(
                        ['user_id' => $id, 'article_id' => $articleId],
                        CacheKey::COUNTER_USER_ARTICLE,
                        [$key => $total]
                    );
                    // log info
                    $info = "[$index/$finish] set cache key `$cacheKey` - ".$key." {$this->sort} to (int) $total";
                    $this->info($info);
                if ($total) $this->logger($info, false, 'script');
                    $index++;
                }
            }
        }, 'user_id');
        return 1;
    }

    /**
     * get sub user
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|mixed
     */
    private function _getSubModel()
    {
        $subMode = User::getModel()
            ->select(['id', 'user_id'])
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE);
        return $subMode;
    }

}
